package com.hatom.cameraxhelp.fragment.face;

import android.annotation.SuppressLint;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.FaceDetector;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.internal.utils.ImageUtil;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.common.util.concurrent.ListenableFuture;
import com.hatom.cameraxhelp.R;
import com.hatom.cameraxhelp.widgets.MultFaceBorderView;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * @author tangxianfeng
 * 自己处理预览数据返回的页面
 * 可参考扩展实现
 */
public class FaceCameraFragment extends Fragment {


    private ProcessCameraProvider cameraProvider;
    private Preview previewView;
    private PreviewView camera_preview;

    private ImageAnalysis imageAnalysis;//预览流分析
    private MultFaceBorderView faceShowView;//识别框
    private AppCompatTextView img_resulttext;//存放识别结果
    private LinearLayout img_reshow;//重新识别img展示
    private LinearLayout small_linear;//存放人脸小图的容器
    private ArrayList<Bitmap> showBitmaps=new ArrayList<>();//小图bitmap

    private boolean isBackCamera= true;//是否为后置摄像 默认是
    public FaceCameraFragment() {

    }

    public static FaceCameraFragment newInstance() {
        FaceCameraFragment fragment = new FaceCameraFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view= inflater.inflate(R.layout.camerax_fragment_face_camera, container, false);
        initView(view);
        XXPermissions.with(requireActivity())
                .permission(Permission.CAMERA)
                .request(new OnPermissionCallback() {
                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        if (all){
                            setUpCamera();
                        }else {
                            ToastUtils.showShort("相机权限未通过");
                        }
                    }
                });
        return view;
    }


    //布局 监听init
    private void initView(View view) {
        camera_preview = view.findViewById(R.id.face_camera_preview);
        faceShowView =  view.findViewById(R.id.faceshow);
        img_reshow=view.findViewById(R.id.img_reshow);
        img_resulttext=view.findViewById(R.id.img_resulttext);
        img_reshow.setVisibility(View.GONE);

        small_linear=view.findViewById(R.id.small_linear);

        img_reshow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                recycleoldBit();
                small_linear.removeAllViews();
                img_reshow.setVisibility(View.GONE);
                img_resulttext.setText("");
            }
        });
        faceShowView.setGetMultFace(new MultFaceBorderView.GetMultFace() {
            @Override
            public void stayface(final ArrayList<Bitmap> bitmaps) {
                if (bitmaps==null){
                    return;
                }
                recycleoldBit();
                showBitmaps=bitmaps;
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        small_linear.removeAllViews();
                        for (int i=0;i<bitmaps.size();i++){
                            AddImage(i);
                        }
                        img_reshow.setVisibility(View.VISIBLE);
                        img_resulttext.setText("一共识别到"+bitmaps.size()+"条结果");
                    }
                });
                //isStartFaceAnalye=false;//暂停识别
            }//停留次数过多 进行小图展示 用户对此人脸比较确信

            @Override
            public void getprogress(int progress) {

            }
        });
        view.findViewById(R.id.trans_camera).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                transCamera();
            }
        });

    }
    //转换摄像头
    public void transCamera(){
        isBackCamera=!isBackCamera;
        cameraProvider.unbindAll();
        CameraSelector cameraSelector=new CameraSelector.Builder()
                .requireLensFacing(isBackCamera?CameraSelector.LENS_FACING_BACK:CameraSelector.LENS_FACING_FRONT)
                .build();
        cameraProvider.bindToLifecycle(FaceCameraFragment.this,cameraSelector, imageAnalysis, previewView);
    }
    //回收之前的bitmap图片
    private void recycleoldBit(){
        if (showBitmaps!=null){
            for (Bitmap bitmap:showBitmaps){
                bitmap.recycle();
            }//回收之前的图片组
        }
    }

    //添加人脸图到列表
    private void AddImage(int postion){
        ImageView imageView=new ImageView(requireActivity());
        imageView.setImageBitmap(showBitmaps.get(postion));
        imageView.setLayoutParams(new ViewGroup.LayoutParams(dip2px(100),dip2px(100)));
        addlistener(imageView,postion);
        small_linear.addView(imageView);
    }
    //绑定监听
    private void addlistener(ImageView imageView, final int postion){
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (showBitmaps!=null&&showBitmaps.get(postion)!=null){

                }
            }
        });//跳转详情页 单人脸
    }

    //DP转换
    public int dip2px( float dpValue) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    //初始化相机
    private void setUpCamera() {
        ExecutorService cameraExecutor = Executors.newSingleThreadExecutor();

        imageAnalysis = new ImageAnalysis.Builder()
                .setTargetRotation(Surface.ROTATION_0)//0度旋转
                .setTargetAspectRatio(AspectRatio.RATIO_4_3)//设置宽高比
                .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)//默认用最新的流图
                .setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888) //默认是YUV 420格式
                .build();//图片分析对象


        imageAnalysis.setAnalyzer(cameraExecutor, new ImageAnalysis.Analyzer() {
            @Override
            public void analyze(@NonNull @NotNull ImageProxy imageProxy) {
                new FaceDetectTask(imageProxy).execute();//执行人脸识别
            }
        });


        final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(requireActivity());
        cameraProviderFuture.addListener(new Runnable() {
            @Override
            public void run() {
                // CameraProvider
                try {
                    cameraProvider = cameraProviderFuture.get();
                } catch (ExecutionException | InterruptedException e) {
                    e.printStackTrace();
                }
                previewView = new Preview.Builder()
                        .setTargetAspectRatio(AspectRatio.RATIO_4_3)
                        .build();
                previewView.setSurfaceProvider(camera_preview.getSurfaceProvider());
                cameraProvider.unbindAll();
                cameraProvider.bindToLifecycle(FaceCameraFragment.this, CameraSelector.DEFAULT_BACK_CAMERA, imageAnalysis, previewView);
            }
        }, ContextCompat.getMainExecutor(requireActivity()));
    }

    /**
     * 人脸检测Task
     */
    private class FaceDetectTask extends ThreadUtils.SimpleTask<Void> {

        private final ImageProxy imageProxy;

        public FaceDetectTask(ImageProxy imageProxy) {
            this.imageProxy = imageProxy;
        }

        @Override
        public Void doInBackground() {
            if (img_reshow.getVisibility()==View.GONE){//当重新识别不可见时进行识别
                detectFaceByPhoneSystem(imageProxy);//执行人脸识别
            }else {
                faceShowView.removeRect();//移除原识别框
            }
            imageProxy.close();
            return null;
        }

        @Override
        public void onSuccess(Void result) {

        }

        public void execute() {
            ThreadUtils.executeByCpu(this);
        }

        @SuppressLint("RestrictedApi")
        public void detectFaceByPhoneSystem(@NonNull ImageProxy imageProxy) {
            Bitmap rgbBitmap = null;
            try {
                rgbBitmap = ImageUtils.getBitmap(Objects.requireNonNull(ImageUtil.yuvImageToJpegByteArray(imageProxy, new Rect(0, 0, imageProxy.getWidth(), imageProxy.getHeight()), 80)), 0)
                        .copy(Bitmap.Config.RGB_565, true);
            } catch (ImageUtil.CodecFailedException e) {
                e.printStackTrace();
            }
            // 获取数据旋转角
            int rotate = imageProxy.getImageInfo().getRotationDegrees();
            Bitmap bitmap;
            if (rgbBitmap==null){
                return;
            }
            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                rotate = rotate + 90;

                Matrix matrix = new Matrix();
                matrix.setRotate(rotate, 0, 0);
                float[] values = {-1f, 0.0f, 0.0f, 0.0f, 1f, 0.0f, 0.0f, 0.0f, 1.0f};
                matrix.setValues(values);
                bitmap = Bitmap.createBitmap(rgbBitmap, 0, 0, rgbBitmap.getWidth(), rgbBitmap.getHeight(), matrix, true);
            } else {
                if (!isBackCamera){
                    Matrix matrix = new Matrix();
                    float[] values = {-1f,0.0f,0.0f,0.0f,1f,0.0f,0.0f,0.0f,1.0f};
                    matrix.setValues(values);
                    matrix.preRotate(rotate);//矩阵前乘
                    bitmap = Bitmap.createBitmap(rgbBitmap, 0, 0, rgbBitmap.getWidth(), rgbBitmap.getHeight(), matrix, true);

                }else {
                    bitmap = ImageUtils.rotate(rgbBitmap, rotate, 0, 0);
                }
            }
            assert bitmap != null;
            float scaleX = (float) camera_preview.getWidth() / bitmap.getWidth();
            float scaleY = (float) camera_preview.getHeight() / bitmap.getHeight();
            FaceDetector detector = new FaceDetector(bitmap.getWidth(), bitmap.getHeight(), 10);
            FaceDetector.Face[] faces = new FaceDetector.Face[10];
            int number = detector.findFaces(bitmap, faces);

            if (number > 0) {
                faceShowView.updateFaces(faces, scaleX, scaleY, number, bitmap);
            } else {
                faceShowView.removeRect();
            }
        }
    }
}